<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/6/3/003
 * Time: 13:26
 */
namespace app\common\job;
use app\user\model\MiaoLog;
use app\user\model\User;
use app\user\model\UserInvite;
use app\user\model\UserLevel;
use app\user\model\UserWallet;
use app\user\model\WalletOperationLog;
use think\facade\Db;
use think\facade\Log;
use think\queue\Job;
class TeamSettlementJob
{
    // 描述说明
    public $desc = '团队结算队列';


    /**
     * fire方法是消息队列默认调用的方法
     * @param Job            $job      当前的任务对象
     * @param array|mixed    $data     发布任务时自定义的数据
     */
    public function fire(Job $job,$data)
    {
        ini_set('memory_limit','512M');
        //send_telegram($msg);
        $this->_doJob($data);
        // 一定要删除  不然会重复跑
        $job->delete();
        return;
    }

    /**
     * 业务处理  逻辑开始
     *
     * @param $data
     * @return bool|int
     */
    private function _doJob($data){
        fileLog(date('y-m-d h:i:s').'开始团队结算队列...',(date('Y-m-d').'_TeamSettlementJob.log'));
        Log::write($data,'----------'.$this->desc.'--处理开始---------'.date('Y-m-d H;i:s'));
        $order = $data['order']??[];
        $oid = $order['id']??0;
        try{
            if(empty($data)||!is_array($data)) exception('数据为空!');
            if(empty($order)||!is_array($order)) exception('订单数据为空!');
            if(empty($data['uid'])) exception('用户信息为空!');
            $userInviteModel = new UserInvite();
            $miaoModel = new MiaoLog();
            $userModel = new User();
            #获取上级关系链
            $total = 0;
            foreach($order as $v){ $total += $v['total'];$oid=$v['order_id']; }
            $userTeam = $userInviteModel->where(['uid'=>$data['uid']])->find();
            $puserTeam = [];
            if(!empty($userTeam['upid']))
                $puserTeam = $userInviteModel->where(['uid'=>$userTeam['upid']])->find();
            if(empty($puserTeam)){
                $wallet = ['uid'=>$data['uid'],'reward'=>$total,'status'=>1,'type'=>5,'extend'=>'user_volume','extend_id'=>$oid,'add_time'=>time(),'describe'=>'个人累计消费'];
                (new WalletOperationLog())->insert($wallet);
                return true;
            }
            $arr = explode(',',$puserTeam['level']);
            $pids = array_diff($arr,[$puserTeam['upid']]);
            $userIds = array_merge([$data['uid'],$puserTeam['uid'],$puserTeam['upid']],array_reverse($pids));
            #获取等级配置
            $levelInfo = [];
            $level = (new UserLevel())->field('id,team,team_twe,manage,level as level_val')->where(['is_delete'=>0])->select()->toArray();#会员等级信息
            foreach($level as $key=>$val){ $levelInfo[$val['id']] = $val; } //根据用户等级和等级表id 进行建名关联
            #获取用户/钱包数据
            $userInfo = $userModel->field('id,level,binding_time')->whereIn('id',$userIds)->select()->toArray();
            $userInvite = [];
            $userM = [];
            #将用户/钱包/等级信息按原排序组装
            foreach($userIds as $kk=>$vv){
                foreach($userInfo as $k=>$v){
                    if($v['id'] == $data['uid']) $userM = empty($userM)? $v : array_merge($userM, $v);
                    if($v['id'] == $vv && $v['id']!=$data['uid']){
                        $userInvite[$kk] = empty($userInvite[$kk])? $v : array_merge($userInvite[$kk], $v);
                    }
                }
            }
            foreach($userInvite as $key=>$val){
                $userInvite[$key]['team'] = 0;
                $userInvite[$key]['team_twe'] = 0;
                $userInvite[$key]['manage'] = 0;
                $userInvite[$key]['commit_manage'] = 0;
                $userInvite[$key]['commit_team'] = 0;
                $userInvite[$key]['ratio'] = 0;
                if(isset($levelInfo[$val['level']]) && $val['level'] == $levelInfo[$val['level']]['id']){
                    $userInvite[$key]['team'] = ($levelInfo[$val['level']]['team']>0) ? $levelInfo[$val['level']]['team']/1000 : 0;
                    $userInvite[$key]['team_twe'] = ($levelInfo[$val['level']]['team_twe']>0) ? $levelInfo[$val['level']]['team_twe']/1000 : 0;
                    $userInvite[$key]['manage'] = ($levelInfo[$val['level']]['manage']>0) ? $levelInfo[$val['level']]['manage']/1000 : 0;
                }
                if($val['id'] == $puserTeam['uid']){
                    $userInvite[$key]['ratio'] = $userInvite[$key]['team'];
                    $userInvite[$key]['commit_team'] = $userInvite[$key]['team']*$total;
                }
                if($val['id'] == $puserTeam['upid']){
                    $userInvite[$key]['ratio'] = $userInvite[$key]['team_twe'];
                    $userInvite[$key]['commit_team'] = $userInvite[$key]['team_twe']*$total;
                }
            }
            #按等级进行分佣,团队只算2级，之后算津贴，每级递减百分之20
            $pows = 0.8;
            $pows_num = 1;
            $manage_commit = $manage_commit_val = 0;
            foreach($userInvite as $item=>$value){
                if($value['id'] == $data['uid'] || $value['id'] == $puserTeam['uid'] || $value['id'] == $puserTeam['upid']) continue;
                if($manage_commit > 0){
                    if($value['level']>1 && getformat(($value['manage']*$total*pow($pows,$pows_num))*100) < 1) $manage_commit_val = 1;
                    else $manage_commit_val = (int)getformat(($value['manage']*$total*pow($pows,$pows_num))*100);
                    $userInvite[$item]['ratio'] = $value['manage']*pow($pows,$pows_num);
                    $pows_num++;
                }else{
                    $userInvite[$item]['ratio'] = $value['manage'];
                    $manage_commit_val = $value['manage']*$total;
                }
                $userInvite[$item]['commit_manage'] = $manage_commit_val;
                $manage_commit++;
            }
            $miao = $wallet = [];$i = 0;$time = time();
            Db::startTrans();
            foreach($userInvite as $k=>$v){
                $commit = $v['commit_team']+$v['commit_manage'];
                if($commit > 0){
                    $miao[$i] = [
                        'uid'=>$v['id'],
                        'oid'=>$oid,
                        'type'=>3,
                        'order_type'=>1,
                        'reward'=>(int)$commit,
                        'status'=>1,
                        'money'=>$total,'proportion'=>$v['ratio']*1000,
                        'add_time'=>$time
                    ];
                    ++$i;
                }
            }
            fileLog(date('Y-m-dHis',time()).'--团队结算：'.json_encode(['userInvite'=>$userInvite,'order'=>$order,'miao'=>$miao]),(date('Y-m-d').'_TeamSettlementJob.log'));
            if(!empty($miao)){
                $miao = array_values($miao);
                if($miaoModel->insertAll($miao)){
                    Db::commit();
                    fileLog(date('y-m-d h:i:s').'---结束---团队结算队列...完成',(date('Y-m-d').'_TeamSettlementJob.log'));
                    Log::write($data,'----------'.$this->desc.'--处理完成---------'.date('Y-m-d H;i:s'));
                    return true;
                }
                exception('miao_log 新增失败!');
            }else{
                fileLog(date('y-m-d h:i:s').'---结束---团队结算队列...没有miao_log',(date('Y-m-d').'_TeamSettlementJob.log'));
            }
        }catch (\Exception $e){
            Db::rollback();
            fileLog(date('Y-m-dHis',time()).'--团队结算--异常：'.json_encode(['data'=>$data,'err'=>$e->getTrace()[0],'msg'=>$e->getMessage()]),(date('Y-m-d').'_TeamSettlementJob_err.log'));
        }
        fileLog(date('y-m-d h:i:s').'---结束---团队结算队列...',date('Y-m-d').'_TeamSettlementJob_err.log');
        return false;
    }

    /**
     * 业务处理  逻辑开始
     *
     * @param $data
     * @return bool|int
     */
    private function _doJobtttt($data){
        fileLog(date('y-m-d h:i:s').'开始团队结算队列...',(date('Y-m-d').'_TeamSettlementJob.log'));
        Log::write($data,'----------'.$this->desc.'--处理开始---------'.date('Y-m-d H;i:s'));
        $order = $data['order']??[];
        $oid = $order['id']??0;
        try{
            if(empty($data)||!is_array($data)) exception('数据为空!');
            if(empty($order)||!is_array($order)) exception('订单数据为空!');
            if(empty($data['uid'])) exception('用户信息为空!');
            #开启团队累计
            $userInvite = (new UserInvite())->loopTop($data['uid']);
            $userModel = new User();
            if(empty($userInvite)){
                $userInvite = $userModel->where(['id'=>$data['uid'],'is_delete'=>0])->field('id as uid,invite_id as upid,0 as pid,level')->select();
                if(!empty($userInvite)) $userInvite = $userInvite->toArray();
                else exception('没有参与结算用户!');
            }
            #用户按等级排序
            $last_names = array_column($userInvite,'pid');
            array_multisort($last_names,SORT_DESC,$userInvite);
            $level = (new UserLevel())->field('id,team,manage,level as level_val')->where(['is_delete'=>0])->select()->toArray();#会员等级信息
            $levelInfo = [];
            $miaoModel = new MiaoLog();
            foreach($level as $key=>$val){ $levelInfo[$val['id']] = $val; } //根据用户等级和等级表id 进行建名关联
            $topUser = $userModel->where(['id'=>$userInvite[count($last_names)-1]['upid']])->field('id as uid,invite_id as upid,0 as pid,level')->find();
            if(!empty($topUser)){
                array_push($userInvite,$topUser); #如果存在上级则追加到数组末尾
                if($topUser['upid'] > 0){
                    $topUser = $userModel->where(['id'=>$topUser['upid']])->field('id as uid,invite_id as upid,0 as pid,level')->find();
                    if(!empty($topUser)){
                        array_push($userInvite,$topUser); #再次判断上级，如果存在上级则追加到数组末尾
                    }
                }
            }
            #组装用户信息和等级信息
            foreach($userInvite as $kk=>$vv){
                if($vv['level'] == $levelInfo[$vv['level']]['id']){
                    $userInvite[$kk]['team'] = ($levelInfo[$vv['level']]['team']>0) ? $levelInfo[$vv['level']]['team']/100 : 0;
                    $userInvite[$kk]['manage'] = ($levelInfo[$vv['level']]['manage']>0) ? $levelInfo[$vv['level']]['manage']/1000 : 0;
                }
            }
            #按等级进行分佣 同等级按管理津贴算，非同等级按团队佣金算
            $total = 0;
            foreach($order as $v){ $total += $v['total'];$oid=$v['order_id']; }
            /*foreach($userInvite as $item=>$value){
                if($item > 0){
                    if($value['level'] > $userInvite[$item-1]['level']){
                        if(isset($userInvite[$item-1]['commit'])&&!empty($total*$userInvite[$item-1]['team']))
                            $userInvite[$item]['commit'] = ($total*$value['team'])-($total*$userInvite[$item-1]['team']);
                        else
                            $userInvite[$item]['commit'] = $total*$value['team'];
                        $userInvite[$item]['manage_commit'] = 0;
                    }else{
                        $userInvite[$item]['commit'] = 0;
                        $userInvite[$item]['manage_commit'] = $total*$value['manage'];
                    }
                }else{
                    $userInvite[$item]['commit'] = $total*$value['team'];
                    $userInvite[$item]['manage_commit'] = 0;
                }
            }*/
            $levels = 0;#遍历后判断用户等级比$level高则赋值给$level，如果出现等级 1->5->3->5->2则出现第一个5之后不能再分佣只能得到管理津贴
            foreach($userInvite as $item=>$value){
                if($item > 0){
                    #判断用户等级是否比$level高，低则取管理津贴
                    if($value['level'] > $levels){
                        #判断用户是否有团队分佣
                        if(!empty($value['team'])&&$value['team']>0){
                            #判断前面是否有用户取得团队分佣
                            if(!empty($levelInfo[$levels]['team'])&&$levelInfo[$levels]['team']>0){
                                if($value['team'] > ($levelInfo[$levels]['team']/100)) $userInvite[$item]['commit'] = ($total*$value['team'])-($total*($levelInfo[$levels]['team']/100));
                                else $userInvite[$item]['commit'] = 0; #前面有用户取得团队分佣，计算用户当前团队分佣比例是否比前面用户的高，高则计算出当前用户佣金并减掉前面用户的佣金，低则不分佣
                            }else $userInvite[$item]['commit'] = $total*$value['team']; #前面无用户取得团队分佣，直接计算用户当前团队佣金
                        }
                        #如果前面有用户取得团队分佣，并且用户当前团队分佣比例比前面用户的低则计算管理津贴
                        if(!empty($levelInfo[$levels]['team'])&&$value['team'] <= ($levelInfo[$levels]['team']/100)&&!empty($value['manage'])&&$value['manage']>0)
                            $userInvite[$item]['manage_commit'] = $total*$value['manage'];
                        else
                            $userInvite[$item]['manage_commit'] = 0;
                        $levels = $value['level'];
                    }else{
                        $userInvite[$item]['commit'] = 0;
                        $userInvite[$item]['manage_commit'] = $total*$value['manage'];
                    }
                }else{
                    $levels = $value['level'];
                    $userInvite[$item]['commit'] = $total*($value['team']??0);
                    $userInvite[$item]['manage_commit'] = 0;
                }
            }
            $miao = $wallet = [];$i = 0;$time = time();
            Db::startTrans();
            foreach($userInvite as $k=>$v){
                if(($v['commit']+$v['manage_commit']) > 0){
                    $miao[$i] = [
                        'uid'=>$v['uid'],
                        'oid'=>$oid,
                        'type'=>3,
                        'order_type'=>1,
                        'reward'=>($v['commit']+$v['manage_commit']),
                        'status'=>1,
                        'money'=>$total,'proportion'=>($v['commit']>0 ? $v['team'] : $v['manage']),
                        'add_time'=>$time
                    ];
                    ++$i;
                }
            }
            fileLog(date('Y-m-dHis',time()).'--团队结算：'.json_encode(['userInvite'=>$userInvite,'order'=>$order,'miao'=>$miao]),(date('Y-m-d').'_TeamSettlementJob.log'));
            if(!empty($miao)){
                $miao = array_values($miao);
                if($miaoModel->insertAll($miao)){
                    Db::commit();
                    fileLog(date('y-m-d h:i:s').'---结束---团队结算队列...完成',(date('Y-m-d').'_TeamSettlementJob.log'));
                    Log::write($data,'----------'.$this->desc.'--处理完成---------'.date('Y-m-d H;i:s'));
                    return true;
                }
                exception('miao_log 新增失败!');
            }else{
                fileLog(date('y-m-d h:i:s').'---结束---团队结算队列...没有miao_log',(date('Y-m-d').'_TeamSettlementJob.log'));
            }
        }catch (\Exception $e){
            Db::rollback();
            fileLog(date('Y-m-dHis',time()).'--团队结算--异常：'.json_encode(['data'=>$data,'err'=>$e->getMessage()]),(date('Y-m-d').'_TeamSettlementJob_err.log'));
        }
        fileLog(date('y-m-d h:i:s').'---结束---团队结算队列...',date('Y-m-d').'_TeamSettlementJob_err.log');
        return false;
    }

    // 处理失败
    public function failed($data){
        fileLog(date('y-m-d h:i:s').'---失败---团队结算队列...',(date('Y-m-d').'_TeamSettlementJob_err.log'));
        Log::write($data,'----------'.$this->desc.'---处理失败，请处理-----------'.date('Y-m-d H;i:s'));
    }
}